<?php

namespace app\common\business;

use app\common\lib\Curl;
use app\common\lib\Status;
use app\common\lib\Str;
use app\common\lib\Time;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\facade\Cache;

class User
{

    public $model = null;

    public function __construct()
    {
        $this->model = new \app\common\model\mysql\User();
    }

    public function login($data)
    {
        if (empty($data['js_code'])){
            throw new Exception("登录凭证code必须");
        }

        $jsCode = $data['js_code'];
        $wechat=LocationConfig::getConfByLocation();
        $url = $wechat['login_url'].'appid='.$wechat['app_id'].'&secret='.$wechat['app_secret'].'&js_code='.$jsCode.'&grant_type=authorization_code';

        try {
            $rs = json_decode(Curl::curlGetContents($url),true);
        } catch (\Exception $e) {
            throw new Exception("错误码：".$e->getCode()."，错误信息：".$e->getMessage());
        }

        if(empty($rs['openid'])){
            throw new Exception("获取用户唯一标识openid失败");
        }

        //判断user表中有无该open_id
        $openId = $rs['openid'];
        $user = $this->getNormalUserByField('open_id',$openId,'id,name,phone_number,sex,avatar,id_card,status,autherized');
        if(!$user){
            //无则新增
            $userData = [
                'open_id' => $openId,
                'status' => config('status.mysql.table_normal'),
                'avatar' => Str::globalRequestDomain().'/uploads/default_photo.png',
                'create_time' => time()
            ];

            //try catch的使用
            //避免暴露数据库原始异常
            try {
                $this->model->save($userData);

            } catch (\Exception $e) {
                throw new Exception("数据库内部异常");
            }

            $userId = $this->model->id;
            $user = null;//返回空数组

            //同时新增userInfo
            $userInfoData = [
                'user_id' => $userId,
                'status' => config('status.mysql.table_normal'),
                'create_time' => time()
            ];
            try {
                (new \app\common\model\mysql\UserInfo())->save($userInfoData);
            } catch (\Exception $e) {
                throw new Exception("数据库内部异常");
            }
        }else{
            //有则更新
            $userId = $user['id'];
            $userData = [
                //'open_id' => $openId,
                //'status' => config('status.mysql.table_normal'),
                'last_login_time' => time(),
                'last_login_ip' => request()->ip(),
            ];

            try {
                $this->model->updateById($userId,$userData);
            } catch (\Exception $e) {
                throw new Exception("数据库内部异常");
            }

            $user['sexText'] = Status::getInfoText('user.sex',$user['sex']);
            unset($user['open_id']);

            //返回数据，判断有手机号时才返回
            !$this->checkUserByPhoneNumber($user['phone_number']) && $user = null;
        }

        //生成
        $token = Str::getLoginToken($openId);
        $redisData = [
            "id" => $userId,
            "open_id" => $openId,
        ];

        $res = cache(config("redis.token_pre") . $token, $redisData, Time::userLoginExpiresTime(1));//过期时间 1：7天 2：30天，默认30天

        return $res ? ["token" => $token, "user" => $user] : false;
    }

    public function dealPhoneNumber($userId,$data)
    {
        if (empty($userId)){
            throw new Exception("用户ID必须");
        }
        if (empty($data['js_code'])){
            throw new Exception("登录凭证code必须");
        }
        /*$user = $this->getNormalUserById($userId);
        if(empty($user)){
            throw new Exception("用户不存在");
        }*/

        $jsCode = $data['js_code'];
        $accessToken = $this->getAccessToken();
        $wechat=LocationConfig::getConfByLocation();
        $url = $wechat['get_phone_url'].'access_token='.$accessToken;

        try {
            $rs = json_decode(Curl::curlGetContents($url,'POST',['code'=>$jsCode]),true);
        } catch (\Exception $e) {
            throw new Exception("错误码：".$e->getCode()."，错误信息：".$e->getMessage());
        }

        if (!isset($rs['phone_info'])){
            throw new Exception("获取用户手机号失败");
        }

        $phone = $rs['phone_info']['purePhoneNumber'];
        if(empty($phone)){
            throw new Exception("获取用户手机号失败");
        }

        $userInfo = $this->getNormalUserByField('phone_number',$phone);
        if ($userInfo && $userInfo['id'] != $userId){
            throw new Exception("该手机号已经存在，请重新设置");
        }

        $userData = [
            'phone_number' => $phone,
        ];
        try {
            $result = $this->updateData($userId,$userData);
        } catch (\Exception $e) {
            throw new Exception("数据库内部异常");
        }

        return $result;
    }

    public function getAccessToken(){
        $wechat=LocationConfig::getConfByLocation();
        $accessToken = cache(config("redis.wx_access_token_pre") . $wechat['app_id']);
        if ($accessToken){
            $res = $accessToken;
        }else{
            $url=$wechat['get_access_token_url'].'appid='.$wechat['app_id'].'&secret='.$wechat['app_secret'].'&grant_type=client_credential';
            try {
                $rs = json_decode(Curl::curlGetContents($url),true);
            } catch (\Exception $e) {
                throw new Exception("错误码：".$e->getCode()."，错误信息：".$e->getMessage());
            }

            if(empty($rs['access_token']) || empty($rs['expires_in'])){
                throw new Exception("获取接口调用凭据access_token失败");
            }

            cache(config("redis.wx_access_token_pre") .$wechat['app_id'], $rs['access_token'], $rs['expires_in']);
            $res= $rs['access_token'];
        }
        return $res;
    }

    public function getTopStatistic($id){
        $data = [
            'my_took_job'=>0,
            'my_send_job'=>0,
            'my_collect_work'=>0,
            'my_associated_status'=>'' //关联企业审核状态
        ];

        if (empty($id)){
            return $data;
        }

        //我发的活 - 取全部
        $mapSend = [['user_id','=',$id]];
        $sendJobList = (new Work())->getListByWhere($mapSend,0,0,'id');
        $data['my_send_job'] = count($sendJobList);

        //我接的活 - 只取抢且录用的
        $mapTook = [
            ['user_id','=',$id],
            //['is_employed','=',1]
        ];
        $tookJobList = (new WorkRob())->getListByWhere($mapTook,0,0,'id');
        $data['my_took_job'] = count($tookJobList);

        //我的收藏
        $mapCollect = [['user_id','=',$id]];
        $collectJobList = (new WorkCollect())->getListByWhere($mapCollect,0,0,'id');
        $data['my_collect_work'] = count($collectJobList);

        //关联企业审核状态
        $userAssociationInfo = (new \app\common\business\UserAssociation())->getNormalSimpleInfoByField('user_id',$id);
        if (!empty($userAssociationInfo)){
            $data['my_associated_status'] = config('user.association_status')[$userAssociationInfo['audit']] ?? '';
        }
        return $data;
    }

    public function updateData($id, $data)
    {
        $user = self::getNormalUserById($id);
        if (!$user) {
            throw new Exception("不存在该用户");
        }

        return $this->model->updateById($id, $data);
    }

    public function getNormalUserByField($field,$value,$selectField = '*')
    {
        $user = $this->model->getNormalByField($field,$value,$selectField);
        if (!$user || $user->status != config("status.mysql.table_normal")) {
            return [];
        }
        return $user->toArray();
    }

    public function getNormalUserById($id)
    {
        $user = $this->model->getById($id);
        if (!$user || $user->status != config("status.mysql.table_normal")) {
            return [];
        }
        return $user->toArray();
    }

    /**
     * 通过手机号判断是否返回用户信息
     * 有手机号时才认定是真实用户
     * @param $phone_number
     * @return bool
     */
    public function checkUserByPhoneNumber($phone_number): bool
    {
        $flag = false;
        !empty($phone_number) && $flag = true;
        return $flag;
    }

    /**
     * 判断是否实名认证
     * 1yes 2no
     * @param $autherized
     * @return bool
     */
    public function checkIsAutherized($autherized){
        $flag = false;
        $autherized == 1 && $flag = true;
        return $flag;
    }

    /*public function update($id, $data)
    {
        $user = self::getNormalUserById($id);
        if (!$user) {
            throw new Exception("不存在该用户");
        }

        //检查用户名是否存在
        $userResult = $this->getNormalUserByUsername($data['username']);
        if ($userResult && $userResult['id'] != $id) {
            throw new Exception("该用户已经存在，请重新设置");
        }
        return $this->model->updateById($id, $data);
    }*/

    /**
     * @param $where
     * @param $page
     * @param $limit
     * @param string $field
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getListByWhere($where,$page,$limit,$field='*'){
        $where[] = ['status','=',config("status.mysql.table_normal")];
        if ($page!=0 && $limit !=0){
            $list = $this->model->getPageListByWhere($where,$page,$limit,$field);
        }else{
            $list = $this->model->getNormalListByWhere($where,$field);
        }
        if($list->isEmpty()){
            return [];
        }
        return $list->toArray();
    }

    /**
     * 获取分页列表
     * @throws Exception
     */
    public function getTableList($page=null,$limit=null,$keyword='',$sex='',$userType=0): array
    {
        $where=[
            ['name|phone_number|id_card','like','%'.$keyword.'%']
        ];
        if($sex!==''){
            $where[]=['sex','=',$sex];
        }
        if($userType!=0){
            $where[]=['intention','<>',0];
        }
        $list=$this->model->getTableList($where,$page,$limit);
        $associationBis=new UserAssociation();
        foreach ($list['list'] as $k=>$v){
            $list['list'][$k]=self::resetData($v);
            if(isset($list['list'][$k]['userAssociation'])){
                $list['list'][$k]['userAssociation']=$associationBis->resetData($v['userAssociation']);
            }
        }
        return $list;
    }

    /**
     * 获取详情
     * @throws Exception
     */
    public function getDetail($id): array
    {
        $list=$this->model->getById($id);
        $list=$list->isEmpty()?[]:$list->toArray();
        return self::resetData($list);
    }

    public static function resetData($data){
        if(!empty($data)){
            $data['last_login_time']=empty($data['last_login_time'])?'':Time::formatTheTime($data['last_login_time'],'s');
            $data['autherized_text']=$data['autherized']==1?'已认证':'未认证';
        }
        return $data;
    }
}
